// 题意：主要是求两个串的最长公共前缀
//
// 题解：可以用后缀数组，对于两个串一定是某两个后缀的前缀，而这两个串的
// 最长公共前缀就是其对应到高度数组相应区间的最小值。
//
#include <iostream>
#include <vector>
#include <string>
#include <algorithm>
#include <cmath>

struct suffix_array
{
	typedef std::vector<int> & v_ref;
	typedef std::vector<int> const & v_cref;
	typedef std::string const & s_cref;

	struct suffix_cmp
	{
		suffix_cmp(v_ref rank, int const & gap, int const & len)
			: rank(rank), gap(gap), len(len) {}

		bool operator()(int i, int j)
		{
			if (rank[i] != rank[j]) return rank[i] < rank[j];
			return (i + gap < len && j + gap < len) ?
						(rank[i + gap] < rank[j + gap]) : i > j;
		}

	private:
		v_cref rank;
		int const & gap;
		int const & len;
	};

	suffix_array(s_cref s, v_ref sa, v_ref rank, v_ref height)
		: s(s), sa(sa), rank(rank), height(height)
	{
		tmp_rank.resize(rank.size());
	}

	void build_suffix_array()
	{
		int n = s.size();
		for (int i = 0; i < n; i++) { sa[i] = i; rank[i] = s[i]; }
		for (int gap = 1; ; gap *= 2) {
			suffix_cmp cmp(rank, gap, n);
			std::sort(sa.begin(), sa.begin() + n, cmp);
			for (int i = 0; i < n-1; i++)
				tmp_rank[i + 1] = tmp_rank[i] + cmp(sa[i], sa[i + 1]);
			for (int i = 0; i < n; i++) rank[sa[i]] = tmp_rank[i];
			if (tmp_rank[n - 1] == n - 1) break;
		}
	}

	void build_lcp()
	{
		int n = s.size();
		for (int i = 0, k = 0; i < n; i++)
			if (rank[i] != n-1) {
				for (int j = sa[rank[i] + 1]; s[i + k] == s[j + k]; k++);
				height[rank[i]] = k;
				if (k) k--;
			}
	}

private:
	s_cref s;
	v_ref sa; // suffix array
	v_ref rank;
	v_ref height; // lcp array, longest common prefix array
	std::vector<int> tmp_rank;
};

template <
	class T,
	class COMPARE = std::less<T>
>
struct sparse_table
{
	typedef T value_type;
	typedef unsigned int size_type;
	typedef COMPARE comparer;
	typedef std::vector<value_type> vector_type;

	inline size_type log2(size_type len)
	{
		size_type tmp = 0;
		for (; size_type(1 << tmp) <= len; tmp++); // FIXME 11 neednot write size_type
		return tmp - 1;
	}

	sparse_table(vector_type const & data, comparer cmp = comparer())
		: data(data), cmp(cmp)
	{
		size_type n = data.size();
		size_type len = log2(n);
		st.resize(n);
		for (typename std::vector<vector_type>::iterator it = st.begin();
				it != st.end(); ++it)
			(*it).resize(len + 1);

		for (size_type i = 0; i < n; i++) st[i][0] = i;
		for (size_type l = 1; l <= len; l++)
			for (size_type i = 0; (i + (1<<l) - 1) < n; i++)
				if (cmp(data[ st[i][l - 1] ], data[ st[i + (1<<(l-1))][l - 1] ]))
					st[i][l] = st[i][l - 1];
				else
					st[i][l] = st[i + (1 << (l-1))][l - 1];
	}

	size_type query_interval_index(size_type l, size_type r) // [l, r]
	{
		int k = log2(r - l + 1);
		if (cmp(data[ st[l][k] ], data[ st[r - (1<<k) + 1][k] ]))
			return st[l][k];
		else
			return st[r - (1<<k) + 1][k];
	}

	value_type query_interval(size_type l, size_type r) // [l, r]
	{
		return data[ query_interval_index(l, r) ];
	}

private:
	std::vector<vector_type> st; // store the index of the dest value
	vector_type const & data;
	comparer cmp;
};

int dec_len(int x)
{
	return ((!x) ? 1 : int(std::log10(x)) + 1);
}

int main()
{
	std::ios::sync_with_stdio(false);
	for (std::string s; std::cin >> s; ) {
		std::vector<int> sa(s.size());
		std::vector<int> rank(s.size());
		std::vector<int> height(s.size());
		suffix_array suffix(s, sa, rank, height);
		suffix.build_suffix_array();
		suffix.build_lcp();

		/*
		std::cout << s << '\n';
		for (auto i : sa)
			std::cout << s.substr(i, s.size() - i) << '\n';

		std::cout << "sa:\n";
		for (auto i : sa) std::cout << i << ' ';
		std::cout << "\n\n";

		std::cout << "rank:\n";
		for (auto i : rank) std::cout << i << ' ';
		std::cout << "\n\n";

		std::cout << "height:\n";
		for (auto i : height) std::cout << i << ' ';
		std::cout << "\n\n";
		*/

		int m, prel, prer;
		long long orginal, compressed;
		std::cin >> m;
		std::cin >> prel >> prer;
		orginal = prer - prel + 1;
		compressed = prer - prel + 3;

		sparse_table<int> st(height);

		for (int i = 1, l, r; i < m; i++) {
			std::cin >> l >> r;
			orginal += r - l + 1;
			compressed += r - l + 1;
			int min = std::min(r - l, prer - prel);
			int tl = rank[l], tr = rank[prel];
			if (tl > tr) std::swap(tl, tr);
			if (tl < tr)
				min = std::min(min, st.query_interval(tl, tr-1));
			/*
			std::cout << "min: " << min << '\n';
			std::cout << "dec: " << min - dec_len(min) - 1 << '\n';
			*/
			compressed -= (min - dec_len(min) - 1);
			/*
			std::cout << "compressed: " << compressed << '\n';
			*/

			prel = l;  prer = r;
		}
		std::cout << orginal << ' ' << compressed << '\n';
	}
}

